package com.tanhua.server.interceptor;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.tanhua.common.exception.BusinessException;
import com.tanhua.common.mapper.UserFreezeMapper;
import com.tanhua.common.mapper.UserInfoMapper;
import com.tanhua.common.pojo.User;
import com.tanhua.common.pojo.UserFreeze;
import com.tanhua.common.pojo.UserInfo;
import com.tanhua.common.utils.NoTalkingIntercept;
import com.tanhua.common.utils.PostNotAllowed;
import com.tanhua.common.utils.UserThreadLocal;
import com.tanhua.common.vo.ErrorResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class UserFreezeInterceptor implements HandlerInterceptor {

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private UserFreezeMapper userFreezeMapper;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private final String REDIS_FREEZE_USER = "REDIS_FREEZE_USER";
    private final String REDIS_FREEZE_USER_ID = "REDIS_FREEZE_USER_ID_";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //校验handler是否是HandlerMethod
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        //如果用户请求的HandlerMethod不包含@NoTalkingIntercept或@PostNotAllowed,直接放行
        if (!(((HandlerMethod) handler).hasMethodAnnotation(NoTalkingIntercept.class) || ((HandlerMethod) handler).hasMethodAnnotation(PostNotAllowed.class))) {
            return true;
        }

        /*
            冻结判断:
                1.查询redis,判断用户是否为冻结用户
                2.查询tb_user_info表,根据用户状态(user_status)判断登录用户是否为冻结(2发言或3发布动态)的用户
                3.根据@NoTalkingIntercept/@PostNotAllowed判断用户是: 2冻结发言 3冻结发布动态
         */
        //1.查询redis,判断用户是否为冻结用户
        //获取user对象
        User user = UserThreadLocal.get();
        System.out.println(user);
        if (redisTemplate.opsForHash().hasKey(REDIS_FREEZE_USER, REDIS_FREEZE_USER_ID + user.getId())) {
            //2.查询根据用户id判断登录用户是否为冻结(发言或发布动态)的用户
            //根据用户id获取userInfo对象
            /*LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UserInfo::getUserId, user.getId());
            UserInfo userInfo = userInfoMapper.selectOne(wrapper);*/
            //根据用户id获取userFreeze对象
            LambdaQueryWrapper<UserFreeze> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(UserFreeze::getUserId, user.getId());
            UserFreeze userFreeze = userFreezeMapper.selectOne(wrapper1);
            if (userFreeze.getFreezingRange() == 2) {
                //被冻结发言
                //查询该用户的冻结时间是否已过期限
                //冻结期限的时间戳
                long expireDate = userFreeze.getExpireDate().getTime();
                //获取当前系统时间的毫秒值
                long nowMillisecond = System.currentTimeMillis();
                //判断该用户的冻结时间是否已过期限
                if (nowMillisecond >= expireDate) {
                    //该用户的冻结时间已过期限
                    userFreeze.setReasonsForFreezing("冻结时间期限已过");
                    //放行该请求,并将tb_user_info表中用户状态修改为:1(正常)并进行保存
                    UserInfo userInfo2 = new UserInfo();
                    userInfo2.setUserStatus(1);
                    UpdateWrapper<UserInfo> wrapper2 = new UpdateWrapper<>();
                    wrapper2.eq("user_id", user.getId());
                    userInfoMapper.update(userInfo2, wrapper2);
                } else {
                    //该用户的冻结时间未过期限
                    //判断:若请求的HandlerMethod包含@NoTalkingIntercept注解,拦截该请求
                    if (((HandlerMethod) handler).hasMethodAnnotation(NoTalkingIntercept.class)) {
                        //return false;
                        //抛出异常,提示用户:您的账号已被冻结发言
                        String reasonsForFreezing = userFreeze.getReasonsForFreezing();
                        throw new BusinessException(ErrorResult.talkingBeFreeze(reasonsForFreezing));
                    }
                }
            } else if (userFreeze.getFreezingRange() == 3) {
                //被冻结发布动态
                //查询该用户的冻结时间是否已过期限
                //冻结期限的时间戳
                long expireDate = userFreeze.getExpireDate().getTime();
                //获取当前系统时间的毫秒值
                long nowMillisecond = System.currentTimeMillis();
                //判断该用户的冻结时间是否已过期限
                if (nowMillisecond >= expireDate) {
                    //该用户的冻结时间已过期限
                    userFreeze.setReasonsForFreezing("冻结时间期限已过");
                    //放行该请求,并将tb_user_info表中用户状态修改为:1(正常)并进行保存
                    UserInfo userInfo2 = new UserInfo();
                    userInfo2.setUserStatus(1);
                    UpdateWrapper<UserInfo> wrapper2 = new UpdateWrapper<>();
                    wrapper2.eq("user_id", user.getId());
                    userInfoMapper.update(userInfo2, wrapper2);
                } else {
                    //该用户的冻结时间未过期限
                    //判断:若请求的HandlerMethod包含@PostNotAllowed注解,拦截该请求,
                    if (((HandlerMethod) handler).hasMethodAnnotation(PostNotAllowed.class)) {
                        //return false;
                        //抛出异常,提示用户:您的账号已被冻结发布动态
                        String reasonsForFreezing = userFreeze.getReasonsForFreezing();
                        throw new BusinessException(ErrorResult.postNotAllowedBeFreeze(reasonsForFreezing));
                    }
                }
            }
        }

        return true;
    }
}